home *** CD-ROM | disk | FTP | other *** search
/ Collection of Tools & Utilities / Collection of Tools and Utilities.iso / graphic / jpegsrc4.zip / JCPIPE.C < prev    next >
C/C++ Source or Header  |  1992-11-10  |  28KB  |  737 lines

  1. /*
  2.  * jcpipe.c
  3.  *
  4.  * Copyright (C) 1991, 1992, Thomas G. Lane.
  5.  * This file is part of the Independent JPEG Group's software.
  6.  * For conditions of distribution and use, see the accompanying README file.
  7.  *
  8.  * This file contains compression pipeline controllers.
  9.  * These routines are invoked via the c_pipeline_controller method.
  10.  *
  11.  * There are four basic pipeline controllers, one for each combination of:
  12.  *    single-scan JPEG file (single component or fully interleaved)
  13.  *  vs. multiple-scan JPEG file (noninterleaved or partially interleaved).
  14.  *
  15.  *    optimization of entropy encoding parameters
  16.  *  vs. usage of default encoding parameters.
  17.  *
  18.  * Note that these conditions determine the needs for "big" arrays:
  19.  * multiple scans imply a big array for splitting the color components;
  20.  * entropy encoding optimization needs a big array for the MCU data.
  21.  *
  22.  * All but the simplest controller (single-scan, no optimization) can be
  23.  * compiled out through configuration options, if you need to make a minimal
  24.  * implementation.
  25.  */
  26.  
  27. #include "jinclude.h"
  28.  
  29.  
  30. /*
  31.  * About the data structures:
  32.  *
  33.  * The processing chunk size for downsampling is referred to in this file as
  34.  * a "row group": a row group is defined as Vk (v_samp_factor) sample rows of
  35.  * any component after downsampling, or Vmax (max_v_samp_factor) unsubsampled
  36.  * rows.  In an interleaved scan each MCU row contains exactly DCTSIZE row
  37.  * groups of each component in the scan.  In a noninterleaved scan an MCU row
  38.  * is one row of blocks, which might not be an integral number of row groups;
  39.  * for convenience we use a buffer of the same size as in interleaved scans,
  40.  * and process Vk MCU rows in each burst of downsampling.
  41.  * To provide context for the downsampling step, we have to retain the last
  42.  * two row groups of the previous MCU row while reading in the next MCU row
  43.  * (or set of Vk MCU rows).  To do this without copying data about, we create
  44.  * a rather strange data structure.  Exactly DCTSIZE+2 row groups of samples
  45.  * are allocated, but we create two different sets of pointers to this array.
  46.  * The second set swaps the last two pairs of row groups.  By working
  47.  * alternately with the two sets of pointers, we can access the data in the
  48.  * desired order.
  49.  */
  50.  
  51.  
  52.  
  53. /*
  54.  * Utility routines: common code for pipeline controllers
  55.  */
  56.  
  57. LOCAL void
  58. interleaved_scan_setup (compress_info_ptr cinfo)
  59. /* Compute all derived info for an interleaved (multi-component) scan */
  60. /* On entry, cinfo->comps_in_scan and cinfo->cur_comp_info[] are set up */
  61. {
  62.   short ci, mcublks;
  63.   jpeg_component_info *compptr;
  64.  
  65.   if (cinfo->comps_in_scan > MAX_COMPS_IN_SCAN)
  66.     ERREXIT(cinfo->emethods, "Too many components for interleaved scan");
  67.  
  68.   cinfo->MCUs_per_row = (cinfo->image_width
  69.              + cinfo->max_h_samp_factor*DCTSIZE - 1)
  70.             / (cinfo->max_h_samp_factor*DCTSIZE);
  71.  
  72.   cinfo->MCU_rows_in_scan = (cinfo->image_height
  73.                  + cinfo->max_v_samp_factor*DCTSIZE - 1)
  74.                 / (cinfo->max_v_samp_factor*DCTSIZE);
  75.   
  76.   cinfo->blocks_in_MCU = 0;
  77.  
  78.   for (ci = 0; ci < cinfo->comps_in_scan; ci++) {
  79.     compptr = cinfo->cur_comp_info[ci];
  80.     /* for interleaved scan, sampling factors give # of blocks per component */
  81.     compptr->MCU_width = compptr->h_samp_factor;
  82.     compptr->MCU_height = compptr->v_samp_factor;
  83.     compptr->MCU_blocks = compptr->MCU_width * compptr->MCU_height;
  84.     /* compute physical dimensions of component */
  85.     compptr->downsampled_width = jround_up(compptr->true_comp_width,
  86.                        (long) (compptr->MCU_width*DCTSIZE));
  87.     compptr->downsampled_height = jround_up(compptr->true_comp_height,
  88.                         (long) (compptr->MCU_height*DCTSIZE));
  89.     /* Sanity check */
  90.     if (compptr->downsampled_width !=
  91.     (cinfo->MCUs_per_row * (compptr->MCU_width*DCTSIZE)))
  92.       ERREXIT(cinfo->emethods, "I'm confused about the image width");
  93.     /* Prepare array describing MCU composition */
  94.     mcublks = compptr->MCU_blocks;
  95.     if (cinfo->blocks_in_MCU + mcublks > MAX_BLOCKS_IN_MCU)
  96.       ERREXIT(cinfo->emethods, "Sampling factors too large for interleaved scan");
  97.     while (mcublks-- > 0) {
  98.       cinfo->MCU_membership[cinfo->blocks_in_MCU++] = ci;
  99.     }
  100.   }
  101.  
  102.   /* Convert restart specified in rows to actual MCU count. */
  103.   /* Note that count must fit in 16 bits, so we provide limiting. */
  104.   if (cinfo->restart_in_rows > 0) {
  105.     long nominal = cinfo->restart_in_rows * cinfo->MCUs_per_row;
  106.     cinfo->restart_interval = (UINT16) MIN(nominal, 65535L);
  107.   }
  108.  
  109.   (*cinfo->methods->c_per_scan_method_selection) (cinfo);
  110. }
  111.  
  112.  
  113. LOCAL void
  114. noninterleaved_scan_setup (compress_info_ptr cinfo)
  115. /* Compute all derived info for a noninterleaved (single-component) scan */
  116. /* On entry, cinfo->comps_in_scan = 1 and cinfo->cur_comp_info[0] is set up */
  117. {
  118.   jpeg_component_info *compptr = cinfo->cur_comp_info[0];
  119.  
  120.   /* for noninterleaved scan, always one block per MCU */
  121.   compptr->MCU_width = 1;
  122.   compptr->MCU_height = 1;
  123.   compptr->MCU_blocks = 1;
  124.   /* compute physical dimensions of component */
  125.   compptr->downsampled_width = jround_up(compptr->true_comp_width,
  126.                      (long) DCTSIZE);
  127.   compptr->downsampled_height = jround_up(compptr->true_comp_height,
  128.                       (long) DCTSIZE);
  129.  
  130.   cinfo->MCUs_per_row = compptr->downsampled_width / DCTSIZE;
  131.   cinfo->MCU_rows_in_scan = compptr->downsampled_height / DCTSIZE;
  132.  
  133.   /* Prepare array describing MCU composition */
  134.   cinfo->blocks_in_MCU = 1;
  135.   cinfo->MCU_membership[0] = 0;
  136.  
  137.   /* Convert restart specified in rows to actual MCU count. */
  138.   /* Note that count must fit in 16 bits, so we provide limiting. */
  139.   if (cinfo->restart_in_rows > 0) {
  140.     long nominal = cinfo->restart_in_rows * cinfo->MCUs_per_row;
  141.     cinfo->restart_interval = (UINT16) MIN(nominal, 65535L);
  142.   }
  143.  
  144.   (*cinfo->methods->c_per_scan_method_selection) (cinfo);
  145. }
  146.  
  147.  
  148.  
  149. LOCAL void
  150. alloc_sampling_buffer (compress_info_ptr cinfo, JSAMPIMAGE fullsize_data[2],
  151.                long fullsize_width)
  152. /* Create a pre-downsampling data buffer having the desired structure */
  153. /* (see comments at head of file) */
  154. {
  155.   short ci, vs, i;
  156.  
  157.   vs = cinfo->max_v_samp_factor; /* row group height */
  158.  
  159.   /* Get top-level space for array pointers */
  160.   fullsize_data[0] = (JSAMPIMAGE) (*cinfo->emethods->alloc_small)
  161.                 (cinfo->num_components * SIZEOF(JSAMPARRAY));
  162.   fullsize_data[1] = (JSAMPIMAGE) (*cinfo->emethods->alloc_small)
  163.                 (cinfo->num_components * SIZEOF(JSAMPARRAY));
  164.  
  165.   for (ci = 0; ci < cinfo->num_components; ci++) {
  166.     /* Allocate the real storage */
  167.     fullsize_data[0][ci] = (*cinfo->emethods->alloc_small_sarray)
  168.                 (fullsize_width,
  169.                 (long) (vs * (DCTSIZE+2)));
  170.     /* Create space for the scrambled-order pointers */
  171.     fullsize_data[1][ci] = (JSAMPARRAY) (*cinfo->emethods->alloc_small)
  172.                 (vs * (DCTSIZE+2) * SIZEOF(JSAMPROW));
  173.     /* Duplicate the first DCTSIZE-2 row groups */
  174.     for (i = 0; i < vs * (DCTSIZE-2); i++) {
  175.       fullsize_data[1][ci][i] = fullsize_data[0][ci][i];
  176.     }
  177.     /* Copy the last four row groups in swapped order */
  178.     for (i = 0; i < vs * 2; i++) {
  179.       fullsize_data[1][ci][vs*DCTSIZE + i] = fullsize_data[0][ci][vs*(DCTSIZE-2) + i];
  180.       fullsize_data[1][ci][vs*(DCTSIZE-2) + i] = fullsize_data[0][ci][vs*DCTSIZE + i];
  181.     }
  182.   }
  183. }
  184.  
  185.  
  186. #if 0                /* this routine not currently needed */
  187.  
  188. LOCAL void
  189. free_sampling_buffer (compress_info_ptr cinfo, JSAMPIMAGE fullsize_data[2])
  190. /* Release a sampling buffer created by alloc_sampling_buffer */
  191. {
  192.   short ci;
  193.  
  194.   for (ci = 0; ci < cinfo->num_components; ci++) {
  195.     /* Free the real storage */
  196.     (*cinfo->emethods->free_small_sarray) (fullsize_data[0][ci]);
  197.     /* Free the scrambled-order pointers */
  198.     (*cinfo->emethods->free_small) ((void *) fullsize_data[1][ci]);
  199.   }
  200.  
  201.   /* Free the top-level space */
  202.   (*cinfo->emethods->free_small) ((void *) fullsize_data[0]);
  203.   (*cinfo->emethods->free_small) ((void *) fullsize_data[1]);
  204. }
  205.  
  206. #endif
  207.  
  208.  
  209. LOCAL void
  210. downsample (compress_info_ptr cinfo,
  211.         JSAMPIMAGE fullsize_data, JSAMPIMAGE sampled_data,
  212.         long fullsize_width,
  213.         short above, short current, short belo